﻿using Exam.infranstuctrue.Dto.other;
using Exam.infranstuctrue.Dto.Request.Stage;
using Exam.infranstuctrue.Dto.Request.StageQuestion;
using Exam.infranstuctrue.Dto.Respones;
using Exam.infranstuctrue.Dto.Respones.Exam;
using Exam.infranstuctrue.Dto.Respones.Stage;
using Exam.infranstuctrue.EFCore;
using Exam.infranstuctrue.IOC;
using Exam.infranstuctrue.Tools;
using Exam.infranstuctrue.Tools.Attributes;
using Exam.Service.Interface;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Exam.Service.Instance
{
    [Iinjection]
    public class StageServer : BaseService, IStageServer
    {
        private readonly StageIOC _stageIOC;
        private readonly ExamIOC _examIOC;

        public StageServer(StageIOC stageIOC, ExamIOC examIOC)
        {
            _stageIOC = stageIOC;
            _examIOC = examIOC;
        }
        /// <summary>
        /// 获取组织
        /// </summary>
        /// <param name="organizationids"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        private string GetOrg(string organizationids, string? token = null)
        {
            string orgname = "";
            var url = "https://change.qiudaoyu.top/api/Organization/GetOrganization";
            var res = Http.Get(url, token);
            var returns = JsonConvert.DeserializeObject<ApiResult>(res);
            var result = JsonConvert.SerializeObject(returns.data);
            var data = JsonConvert.DeserializeObject<List<OrganizationDto>>(result);

            var orgids = data.Select(d => d.id).ToList();
            if (!string.IsNullOrEmpty(organizationids))
            {

                var orgIds = organizationids.Split(",");
                orgname = "";
                foreach (var item2 in orgIds)
                {
                    var iq = data.Where(d => d.id == item2).FirstOrDefault();//得到组织
                    if (iq != null)
                    {
                        orgname += iq.name + ",";
                    }
                    else
                    {
                        var chilre = data.Select(d => d.children).ToList();
                        foreach (var item3 in chilre)
                        {
                            var iq2 = item3.Where(d => d.id == item2).FirstOrDefault();
                            if (iq2 != null)
                            {
                                orgname += iq2.name + ",";
                            }
                        }

                    }
                }
                orgname = orgname.Substring(0, orgname.Length - 1);
            }
            return orgname;
        }
        /// <summary>
        /// 获取闯关列表
        /// </summary>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <param name="key"></param>
        /// <param name="IsBan"></param>
        /// <param name="IsPublic"></param>
        /// <returns></returns>
        public async Task<ApiResult> GetStage(string? token = null, int page = 1, int limit = 10, string? key = "", int IsBan = -1, int IsPublic = -1)
        {
            var stage = await _stageIOC._examStageEFCore.QueryAll(out int total, page, limit, o => o.ScreateTime, false, d => d.Sname.Contains(key)
             && (IsBan == -1 || d.SisBan == IsBan)
             && (IsPublic == -1 || d.SisPublish == IsPublic)).ToListAsync();
            List<StageRes> stageRes = new List<StageRes>();
            foreach (var item in stage)
            {
                stageRes.Add(new StageRes
                {
                    Sid = item.Sid,
                    SbeginTime = item.SbeginTime,
                    SendTime = item.SendTime,
                    Scount = item.Scount,
                    ScreateTime = item.ScreateTime,
                    Sexplain = item.Sexplain,
                    SisBan = item.SisBan,
                    SisPublish = item.SisPublish,
                    Slabel = item.Slabel,
                    Slv = item.Slv,
                    Sname = item.Sname,
                    Sorgs = item.Sorgs,
                    Soname = GetOrg(item.Sorgs, token),
                });
            }
            return GetResult(1, "关卡列表", data: (new
            {
                total = total,
                data = stageRes
            }));
        }
        /// <summary>
        /// 添加关卡
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<ApiResult> AddStage(StageDto dto)
        {
            ExamStage examStage = new ExamStage()
            {
                Sid = Config.GUID(),
                SbeginTime = dto.SbeginTime,
                Scount = dto.Scount,
                ScreateTime = DateTime.Now,
                Sdesc = "",
                SendTime = dto.SendTime,
                Sexplain = dto.Sexplain,
                SisBan = 0,
                SisPublish = 0,
                Sisrepeat = dto.Sisrepeat,
                Slabel = dto.Slabel,
                Slv = dto.Slv,
                Sname = dto.Sname,
                Sno = dto.Sno,
                Sorgs = dto.Sorgs,
                Sphoto = dto.Sphoto,
                Srule = dto.Srule,
                Sstate = 1,
                SpassCount = 0,
                Spart = dto.Spart,
                SruleCount = 0,
                Sseries = dto.Sseries,
            };
            _stageIOC._examStageEFCore.Add(examStage);
            var result = await _stageIOC._examStageEFCore.SaveChangesAsync();
            return GetResult(result > 0 ? 1 : 0, result > 0 ? "添加成功" : "添加失败");

        }
        /// <summary>
        /// 删除关卡
        /// </summary>
        /// <param name="sid"></param>
        /// <returns></returns>
        public async Task<ApiResult> DeleteStage(string sid)
        {
            var stage = await _stageIOC._examStageEFCore.QueryAll(d => d.Sid == sid).FirstOrDefaultAsync();
            var stagedetali = await _stageIOC._examStageDetailEFCore.QueryAll(d => d.Sdsid == sid).ToListAsync();
            if (stage == null)
            {
                return GetResult(0, "没有改关卡");
            }
            if (stage.SisPublish == 1)
            {
                return GetResult(0, "该关卡已发布不可删除");
            }
            if (stagedetali.Any())
            {
                return GetResult(0, "包含子关卡不可删除");
            }
            _stageIOC._examStageEFCore.Delete(stage);
            var result = await _stageIOC._examStageEFCore.SaveChangesAsync();
            return GetResult(result > 0 ? 1 : 0, result > 0 ? "删除成功" : "删除失败");
        }
        /// <summary>
        /// 获取单个关卡
        /// </summary>
        /// <param name="sid"></param>
        /// <returns></returns>
        public async Task<ApiResult> GetEchoStage(string sid)
        {
            var stage = await _stageIOC._examStageEFCore.QueryAll(d => d.Sid == sid).FirstOrDefaultAsync();
            var stagedetali = await _stageIOC._examStageDetailEFCore.QueryAll(o => o.SdcreateTime, false, d => d.Sdsid == stage.Sid).ToListAsync();
            List<StageDetaliRes> stageDetaliRes = new List<StageDetaliRes>();
            foreach (var item in stagedetali)
            {
                stageDetaliRes.Add(new StageDetaliRes
                {
                    Sdsid = item.Sdsid,
                    Sdcount = item.Sdcount,
                    Sdcourse = item.Sdcourse,
                    Sdid = item.Sdid,
                    Sdlabels = item.Sdlabels,
                    SdcreateTime = item.SdcreateTime,
                    SdisBan = item.SdisBan,
                    Sdlv = item.Sdlv,
                    Sdname = item.Sdname,
                    Sdpart = item.Sdpart,
                    SdpassCount = item.SdpassCount,
                    Sdphoto = item.Sdphoto,
                    Sdrule = item.Sdrule,
                    SdtotalTimeStamp = item.SdtotalTimeStamp,
                    SdsingleTimeStamp = item.SdsingleTimeStamp,
                });

            }
            StageRes stageRes = new StageRes()
            {
                Sid = stage.Sid,
                SbeginTime = stage.SbeginTime,
                Scount = stage.Scount,
                ScreateTime = stage.ScreateTime,
                SendTime = stage.SendTime,
                Sexplain = stage.Sexplain,
                Sisrepeat = stage.Sisrepeat,
                Slabel = stage.Slabel,
                Slv = stage.Slv,
                Sname = stage.Sname,
                Sorgs = stage.Sorgs,
                Sphoto = stage.Sphoto,
                Srule = stage.Srule,
                Sseries = stage.Sseries,
                stagedetali = stageDetaliRes,
            };
            return GetResult(1, "单个关卡", stageRes);
        }
        /// <summary>
        /// 修改关卡
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<ApiResult> UpdateStage(StageDto dto)
        {
            var stage = await _stageIOC._examStageEFCore.QueryAll(d => d.Sid == dto.Sid).FirstOrDefaultAsync();
            var stagedetali = await _stageIOC._examStageDetailEFCore.QueryAll(d => d.Sdsid == dto.Sid).ToListAsync();
            if (stage.SisPublish == 1)
            {
                return GetResult(0, "改关卡已发布不可修改");
            }
            if (stagedetali.Any())
            {
                return GetResult(0, "包含子关卡不可修改");
            }
            stage.Scount = dto.Scount;
            stage.Sphoto = dto.Sphoto;
            stage.SbeginTime = dto.SbeginTime;
            stage.SendTime = dto.SendTime;
            stage.Sexplain = dto.Sexplain;
            stage.Srule = dto.Srule;
            stage.Sisrepeat = dto.Sisrepeat;
            stage.Slabel = dto.Slabel;
            stage.Sorgs = dto.Sorgs;
            stage.Sno = dto.Sno;
            _stageIOC._examStageEFCore.Update(stage);
            var result = _stageIOC._examStageEFCore.SaveChanges();
            return GetResult(result > 0 ? 1 : 0, result > 0 ? "修改成功" : "修改失败");
        }
        /// <summary>
        /// 是否禁用
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<ApiResult> StageIsBan(List<StageDto> dto)
        {
            var sids = dto.Select(d => d.Sid).ToList();
            var stage = await _stageIOC._examStageEFCore.QueryAll(d => d.Sid.Contains(d.Sid)).ToListAsync();
            foreach (var item in stage)
            {
                if (item.SisBan == 1)
                {
                    item.SisBan = 0;
                }
                else
                {
                    item.Sstate = 1;
                }
            }
            _stageIOC._examStageEFCore.UpdateRange(stage);
            var result = _stageIOC._examStageEFCore.SaveChanges();
            return GetResult(result > 0 ? 1 : 0, result > 0 ? "修改成功" : "修改失败");
        }
        /// <summary>
        /// 是否发布
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<ApiResult> StageIsPublish(List<StageDto> dto)
        {
            var sids = dto.Select(d => d.Sid).ToList();
            var stage = await _stageIOC._examStageEFCore.QueryAll(d => d.Sid.Contains(d.Sid)).ToListAsync();
            var stagedetalis = await _stageIOC._examStageDetailEFCore.QueryAll(d => 1 == 1).ToListAsync();
            foreach (var item in stage)
            {
                var stagedetali = stagedetalis.Where(d => d.Sdsid == item.Sid).ToList();
                if (stagedetali.Any())
                {
                    return GetResult(0, "其中有包含有子关卡的关卡");
                }
                if (item.SisBan == 1)
                {
                    item.SisBan = 0;
                }
                else
                {
                    item.Sstate = 1;
                }
            }
            _stageIOC._examStageEFCore.UpdateRange(stage);
            var result = _stageIOC._examStageEFCore.SaveChanges();
            return GetResult(result > 0 ? 1 : 0, result > 0 ? "修改成功" : "修改失败");
        }
        /// <summary>
        /// 添加子集关卡
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<ApiResult> AddChilrenStage(StageDetaliDto dto)
        {
            int? lv = 0;
            var stage = await _stageIOC._examStageEFCore.QueryAll(d => d.Sid == dto.Sdsid).FirstOrDefaultAsync();
            var stagedetali = await _stageIOC._examStageDetailEFCore.QueryAll(d => d.Sdsid == dto.Sdsid).ToListAsync();
            if (stagedetali.Any())
            {
                foreach (var item in stagedetali)
                {
                    lv += item.Sdlv;
                }
            }
            var plv = lv / stagedetali.Count();
            if (plv > stage.Slv)
            {
                return GetResult(0, "等级超出限制");
            }
            if (stage == null)
            {
                return GetResult(0, "没有该关卡");
            }
            if (stagedetali.Count() >= stage.Scount)
            {
                return GetResult(0, "内置关卡已满");
            }
            ExamStageDetail examStageDetail = new ExamStageDetail()
            {
                Sdcount = dto.Sdcount,
                Sdcourse = dto.Sdcourse,
                SdcreateTime = DateTime.Now,
                Sdesc = "",
                Sdid = Config.GUID(),
                SdisBan = 0,
                Sdlabels = dto.Sdlabels,
                Sdlv = dto.Sdlv,
                Sdname = dto.Sdname,
                Sdpart = dto.Sdpart,
                SdpassCount = 0,
                Sdphoto = dto.Sdphoto,
                Sdrule = dto.Sdrule,
                Sdsid = dto.Sdsid,
                SdsingleTimeStamp = dto.SdsingleTimeStamp,
                Sdstate = 1,
                SdtotalTimeStamp = dto.SdtotalTimeStamp,
            };
            _stageIOC._examStageDetailEFCore.Add(examStageDetail);
            var result = _stageIOC._examStageDetailEFCore.SaveChanges();
            return GetResult(result > 0 ? 1 : 0, result > 0 ? "添加成功" : "添加失败");
        }
        /// <summary>
        /// 删除子关卡
        /// </summary>
        /// <param name="sdid"></param>
        /// <returns></returns>
        public async Task<ApiResult> DeleteStageChilren(string sdid)
        {
            var history = await _stageIOC._examStageHistoryEFCore.QueryAll(d => d.Shsdid == sdid).ToListAsync();
            var stagedtali = await _stageIOC._examStageDetailEFCore.QueryAll(d => d.Sdid).FirstOrDefaultAsync();
            if (stagedtali == null)
            {
                return GetResult(0, "没有没有此关卡");
            }
            if (history.Any())
            {
                return GetResult(0, "已有人闯关不可删除");
            }
            _stageIOC._examStageDetailEFCore.Delete(stagedtali);
            var result = _stageIOC._examStageDetailEFCore.SaveChanges();
            return GetResult(result > 0 ? 1 : 0, result > 0 ? "删除成功" : "删除失败");
        }
        /// <summary>
        /// 获取单个子集关卡
        /// </summary>
        /// <param name="sdid"></param>
        /// <returns></returns>
        public async Task<ApiResult> GetEchoStageChilren(string sdid)
        {
            var stagedetali = await _stageIOC._examStageDetailEFCore.QueryAll(d => d.Sdid == sdid).FirstOrDefaultAsync();
            var stage = await _stageIOC._examStageEFCore.QueryAll(d => d.Sid == stagedetali.Sdsid).FirstOrDefaultAsync();
            StageDetaliRes stageDetaliRes = new StageDetaliRes();
            stageDetaliRes.Sdid = stagedetali.Sdid;
            stageDetaliRes.sname = stage.Sname;
            stageDetaliRes.Sdname = stagedetali.Sdname;
            stageDetaliRes.Sdcount = stagedetali.Sdcount;
            stageDetaliRes.Sdsid = stagedetali.Sdsid;
            stageDetaliRes.Sdrule = stagedetali.Sdrule;
            stageDetaliRes.Sdphoto = stagedetali.Sdphoto;
            stageDetaliRes.Sdcourse = stagedetali.Sdcourse;
            stageDetaliRes.Sdpart = stagedetali.Sdpart;
            stageDetaliRes.Sdlabels = stagedetali.Sdlabels;
            stageDetaliRes.Sdlv = stagedetali.Sdlv;
            stageDetaliRes.SdtotalTimeStamp = stagedetali.SdtotalTimeStamp;
            stageDetaliRes.SdsingleTimeStamp = stagedetali.SdsingleTimeStamp;
            return GetResult(1, "获取单个子集关卡", stageDetaliRes);
        }
        /// <summary>
        /// 修改关卡子集
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<ApiResult> UpdateStageChilren(StageDetaliDto dto)
        {
            int? lv = dto.Sdlv;
            var stagedetali = await _stageIOC._examStageDetailEFCore.QueryAll(d => d.Sdid == dto.Sdid).FirstOrDefaultAsync();
            var history = await _stageIOC._examStageHistoryEFCore.QueryAll(d => d.Shsdid == dto.Sdid).ToListAsync();
            if (history.Any())
            {
                return GetResult(0, "已经使用过不可更改");
            }
            var stage = await _stageIOC._examStageEFCore.QueryAll(d => d.Sid == dto.Sdsid).FirstOrDefaultAsync();
            var stagedetalis = await _stageIOC._examStageDetailEFCore.QueryAll(d => d.Sdsid == dto.Sdsid).ToListAsync();
            if (stagedetalis.Any())
            {
                foreach (var item in stagedetalis)
                {
                    lv += item.Sdlv;
                }
            }
            var plv = lv / stagedetalis.Count();
            if (plv > stage.Slv)
            {
                return GetResult(0, "等级超出限制");
            }
            stagedetali.Sdlabels = dto.Sdlabels;
            stagedetali.Sdname = dto.Sdname;
            stagedetali.Sdphoto = dto.Sdphoto;
            stagedetali.SdsingleTimeStamp = dto.SdsingleTimeStamp;
            stagedetali.SdtotalTimeStamp = dto.SdtotalTimeStamp;
            stagedetali.Sdlv = dto.Sdlv;
            stagedetali.Sdcount = dto.Sdcount;
            _stageIOC._examStageDetailEFCore.Update(stagedetali);
            var result = _stageIOC._examStageDetailEFCore.SaveChanges();
            return GetResult(result > 0 ? 1 : 0, result > 0 ? "修改成功" : "修改失败");
        }
        /// <summary>
        /// 子集是否禁用
        /// </summary>
        /// <param name="sdid"></param>
        /// <returns></returns>
        public async Task<ApiResult> ChilrenIsBan(string sdid)
        {
            var stagedetali = await _stageIOC._examStageDetailEFCore.QueryAll(d => d.Sdid == sdid).FirstOrDefaultAsync();
            if (stagedetali.SdisBan == 1)
            {
                stagedetali.SdisBan = 0;
            }
            else
            {
                stagedetali.SdisBan = 1;
            }
            _stageIOC._examStageDetailEFCore.Update(stagedetali);
            var result = _stageIOC._examStageDetailEFCore.SaveChanges();
            return GetResult(result > 0 ? 1 : 0, result > 0 ? "修改成功" : "修改失败");
        }
        /// <summary>
        /// 获取指定试题
        /// </summary>
        /// <param name="lable"></param>
        /// <param name="lv"></param>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<ApiResult> GetQuestion(string lable, int lv, int page, int limit, string? key = "")
        {
            var questions = await _examIOC._examQuestionEFCore.QueryAll(out int total, page, limit, o => o.QcreateTime, false, d => d.Qcontent.Contains(key) &&
            d.Qlable.Contains(lable)
            && d.Qlv == lv).ToListAsync();
            var qids = questions.Select(d => d.Qid).ToList();
            var options = await _examIOC._examoptionEFCore.QueryAll(d => qids.Contains(d.Oqid)).ToListAsync();
            List<QuestionRes> questionRes = new List<QuestionRes>();
            foreach (var item in questions)
            {
                var option = options.Where(d => d.Oqid == item.Qid).ToList();
                List<OptionRes> optionRes = new List<OptionRes>();
                foreach (var item2 in option)
                {
                    optionRes.Add(new OptionRes
                    {
                        Oqid = item2.Oqid,
                        Ocontent = item2.Ocontent,
                        Ocreatetime = item2.Ocreatetime,
                        Oid = item2.Oid,
                        OisRight = item2.OisRight,
                    });
                }
                questionRes.Add(new QuestionRes
                {
                    Qid = item.Qid,
                    Qanalysi = item.Qanalysi,
                    Qanswer = item.Qanswer,
                    Qcontent = item.Qcontent,
                    Qexplain = item.Qexplain,
                    Qlable = item.Qlable,
                    Qlv = item.Qlv,
                    Qtype = item.Qtype,
                    opiton = optionRes
                }); ;
            }
            return GetResult(1, "对应试题", questionRes);
        }
        /// <summary>
        /// 获取关卡内试题
        /// </summary>
        /// <param name="sdid"></param>
        /// <returns></returns>
        public async Task<ApiResult> StageGetQuestion(string sdid)
        {
            var stagequestions = await _stageIOC._examStageDetailQuestionEFCore.QueryAll(d => d.Sdqsdid == sdid).ToListAsync();
            var qids = stagequestions.Select(d => d.Sdqqid).ToList();
            var questions = await _examIOC._examQuestionEFCore.QueryAll(d => qids.Contains(d.Qid)).ToListAsync();
            var options = await _examIOC._examoptionEFCore.QueryAll(d => qids.Contains(d.Oqid)).ToListAsync();
            List<QuestionRes> questionRes = new List<QuestionRes>();
            foreach (var item in questions)
            {
                var option = options.Where(d => d.Oqid == item.Qid).ToList();
                List<OptionRes> optionRes = new List<OptionRes>();
                foreach (var item2 in option)
                {
                    optionRes.Add(new OptionRes
                    {
                        Oqid = item2.Oqid,
                        Ocontent = item2.Ocontent,
                        Ocreatetime = item2.Ocreatetime,
                        Oid = item2.Oid,
                        OisRight = item2.OisRight,
                    });
                }
                questionRes.Add(new QuestionRes
                {
                    Qid = item.Qid,
                    Qanalysi = item.Qanalysi,
                    Qanswer = item.Qanswer,
                    Qcontent = item.Qcontent,
                    Qexplain = item.Qexplain,
                    Qlable = item.Qlable,
                    Qlv = item.Qlv,
                    Qtype = item.Qtype,
                    opiton = optionRes
                }); ;
            }
            return GetResult(1, "关卡对应试题", questionRes);
        }
        /// <summary>
        /// 添加关卡试题
        /// </summary>
        /// <param name="sdid"></param>
        /// <returns></returns>
        public async Task<ApiResult> StageAddQuestion(StageQuestionDto dto)
        {
            var stagedetali = await _stageIOC._examStageDetailEFCore.QueryAll(d => d.Sdid == dto.sdid).FirstOrDefaultAsync();
            var stagequestions = await _stageIOC._examStageDetailQuestionEFCore.QueryAll(d => d.Sdqsdid.Contains(dto.sdid)).ToListAsync();
            if (stagedetali == null)
            {
                return GetResult(0, "没有该关卡");
            }
            if (stagedetali.Sdcount <= stagequestions.Count())
            {
                return GetResult(0, "关卡数量已满");
            }
            List<ExamStageDetailQuestion> examStageDetailQuestion = new List<ExamStageDetailQuestion>();
            foreach (var item in dto.qids)
            {
                examStageDetailQuestion.Add(new ExamStageDetailQuestion
                {
                    Sdqid = Config.GUID(),
                    SdqcreateTime = DateTime.Now,
                    SdqtimeStamp = dto.timestamp,
                    Sdqno = dto.no,
                    SdqpassCount = 0,
                    Sdqqid = item.qid,
                    Sdqsdid = dto.sdid
                });
            }
            _stageIOC._examStageDetailQuestionEFCore.AddRange(examStageDetailQuestion);
            var result = _stageIOC._examStageDetailQuestionEFCore.SaveChanges();
            return GetResult(result > 0 ? 1 : 0, result > 0 ? "添加成功" : "添加失败");
        }
        /// <summary>
        /// 删除关卡试题
        /// </summary>
        /// <param name="sdid"></param>
        /// <returns></returns>
        public async Task<ApiResult> StageDeteleQuestion(StageQuestionDto dto)
        {
            var qids = dto.qids.Select(d => d.qid).ToList();
            var stagequestion = await _stageIOC._examStageDetailQuestionEFCore.QueryAll(d => qids.Contains(d.Sdqqid)).ToListAsync();
            _stageIOC._examStageDetailQuestionEFCore.DeleteRange(stagequestion);
            var result = _stageIOC._examStageDetailQuestionEFCore.SaveChanges();
            return GetResult(result > 0 ? 1 : 0, result > 0 ? "删除成功" : "删除失败");
        }
    }
}
